﻿using System;
using Telerik.OpenAccess;
using Telerik.OpenAccess.Metadata;

namespace LINQPad.OpenAccess.Metadata
{
    /// <summary>
    /// <see cref="IContextTypeInfo"/>
    /// </summary>
    public class ContextTypeInfo : IContextTypeInfo
    {
        #region Private

        #region - Vars

        private readonly Type _contextType;
        private readonly bool _hasDefaultConstructor, _hasCustomConstructor;
        private readonly BackendConfiguration _defaultBackendConfiguration;
        private readonly MetadataSource _defaultMetadataSource;
        private readonly string _name;

        #endregion

        #endregion

        #region Public

        #region - Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="ContextTypeInfo" /> class.
        /// </summary>
        /// <param name="contextType">Type of the context.</param>
        /// <param name="defaultBackendConfiguration">The default backend configuration.</param>
        /// <param name="defaultMetadataSource">The default metadata source.</param>
        /// <param name="name">The name.</param>
        /// <exception cref="System.ArgumentNullException">contextType</exception>
        public ContextTypeInfo( Type contextType, BackendConfiguration defaultBackendConfiguration, MetadataSource defaultMetadataSource
                                , bool hasDefaultConstructor, bool hasCustomConstructor, string name = null )
        {
            if ( contextType == null )
                throw new ArgumentNullException( "contextType" );

            this._contextType = contextType;
            this._hasDefaultConstructor = hasDefaultConstructor;
            this._hasCustomConstructor = hasCustomConstructor;
            this._defaultBackendConfiguration = defaultBackendConfiguration;
            this._defaultMetadataSource = defaultMetadataSource;
            this._name = name == null ? contextType.Name : name;
        }

        #endregion

        #endregion

        #region IContextTypeInfo Members

        /// <summary>
        /// Gets the type of the context.
        /// </summary>
        /// <value>
        /// The type of the context.
        /// </value>
        public Type ContextType
        {
            get { return this._contextType; }
        }
        /// <summary>
        /// Gets the default backend configuration.
        /// </summary>
        /// <value>
        /// The default backend configuration.
        /// </value>
        public BackendConfiguration DefaultBackendConfiguration
        {
            get
            {
                return this._defaultBackendConfiguration;
            }
        }

        /// <summary>
        /// Gets the default metadata source.
        /// </summary>
        /// <value>
        /// The default metadata source.
        /// </value>
        public MetadataSource DefaultMetadataSource
        {
            get
            {
                return this._defaultMetadataSource;
            }
        }
        /// <summary>
        /// Gets a value indicating whether the context type provides a custom constructor.
        /// </summary>
        /// <value>
        /// <c>true</c> if the context type provides a custom constructor; otherwise, <c>false</c>.
        /// </value>
        public bool HasCustomConstructor
        {
            get
            {
                return this._hasCustomConstructor;
            }
        }
        /// <summary>
        /// Gets a value indicating whether the context type provides a default constructor.
        /// </summary>
        /// <value>
        /// <c>true</c> if the context type provides a default constructor; otherwise, <c>false</c>.
        /// </value>
        public bool HasDefaultConstructor
        {
            get
            {
                return this._hasDefaultConstructor;
            }
        }
        /// <summary>
        /// Gets the type of the context mapping definition.
        /// </summary>
        /// <value>
        /// The type of the context mapping definition.
        /// </value>
        public MappingDefinitionType? MappingType
        {
            get
            {
                if ( this._defaultMetadataSource == null )
                    return null;
                return this._defaultMetadataSource.GetMappingDefinitionType( );
            }
        }

        /// <summary>
        /// Gets the name.
        /// </summary>
        /// <value>
        /// The name.
        /// </value>
        public string Name
        {
            get { return this._name; }
        }

        #endregion
    }
}